package com.tudouji.project.mt.service.impl;

import java.math.BigDecimal;
import java.util.*;

import com.tudouji.common.enums.InFormChannelEnums;
import com.tudouji.common.exception.CustomException;
import com.tudouji.common.utils.DateUtils;
import com.tudouji.common.utils.IdUtils;
import com.tudouji.common.utils.StringUtils;
import com.tudouji.project.bill.domain.Whinfo;
import com.tudouji.project.bill.domain.Whinform;
import com.tudouji.project.bill.domain.Whinformitem;
import com.tudouji.project.bill.mapper.WhinformMapper;
import com.tudouji.project.bill.mapper.WhinformitemMapper;
import com.tudouji.project.bill.service.IWhinfoService;
import com.tudouji.project.bill.service.impl.WhoutformServiceImpl;
import com.tudouji.project.mt.domain.MtShop;
import com.tudouji.project.mt.domain.MtToken;
import com.tudouji.project.mt.domain.MtWhinitem;
import com.tudouji.project.mt.service.IMtShopService;
import com.tudouji.project.mt.service.IMtTokenService;
import com.tudouji.project.organization.domain.Organization;
import com.tudouji.project.organization.mapper.OrganizationMapper;
import com.tudouji.project.store.mapper.StorehouseroomMapper;
import com.tudouji.project.system.domain.SysUser;
import com.tudouji.project.system.service.impl.BusinesscodeServiceImpl;
import com.tudouji.project.system.service.impl.SysConfigServiceImpl;
import com.tudouji.project.system.service.impl.SysUserServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.tudouji.project.mt.mapper.MtWhinMapper;
import com.tudouji.project.mt.domain.MtWhin;
import com.tudouji.project.mt.service.IMtWhinService;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import static com.tudouji.project.mt.domain.MtShop.whin_state;
import static com.tudouji.project.mt.domain.MtShop.whout_state;

/**
 * 美团入库单主Service业务层处理
 *
 * @author tudouji
 * @date 2023-11-21
 */
@Slf4j
@Service
public class MtWhinServiceImpl implements IMtWhinService {
    @Autowired
    private MtWhinMapper mtWhinMapper;
    @Autowired
    private SysUserServiceImpl sysUserService;
    @Autowired
    private IMtShopService mtShopService;
    @Autowired
    private SysConfigServiceImpl sysConfigService;
    @Autowired
    private BusinesscodeServiceImpl codeService;
    @Autowired
    private OrganizationMapper organizationMapper;
    @Autowired
    private BusinesscodeServiceImpl businesscodeService;
    @Autowired
    private WhinformMapper whinformMapper;
    @Autowired
    private WhinformitemMapper whinformitemMapper;
    @Autowired
    private StorehouseroomMapper storehouseroomMapper;
    @Autowired
    private IWhinfoService whinfoService;
    @Autowired
    private WhoutformServiceImpl whoutformService;
    @Autowired
    private MtPullService mtPullService;
    @Autowired
    private IMtTokenService iMtTokenService;

    /**
     * 查询美团入库单主
     *
     * @param id 美团入库单主ID
     * @return 美团入库单主
     */
    @Override
    public MtWhin selectMtWhinById(Long id) {
        return mtWhinMapper.selectMtWhinById(id);
    }

    /**
     * 查询美团入库单主列表
     *
     * @param mtWhin 美团入库单主
     * @return 美团入库单主
     */
    @Override
    public List<MtWhin> selectMtWhinListPC(MtWhin mtWhin) {
        return mtWhinMapper.selectMtWhinListPC(mtWhin);
    }

    @Override
    public List<MtWhin> selectMtWhinList(MtWhin mtWhin) {
        return mtWhinMapper.selectMtWhinList(mtWhin);
    }

    /**
     * 新增美团入库单主
     *
     * @param mtWhin 美团入库单主
     * @return 结果
     */
    @Override
    public int insertMtWhin(MtWhin mtWhin) {
        mtWhin.setCreateTime(DateUtils.getNowDate());
        return mtWhinMapper.insertMtWhin(mtWhin);
    }

    /**
     * 修改美团入库单主
     *
     * @param mtWhin 美团入库单主
     * @return 结果
     */
    @Override
    public int updateMtWhin(MtWhin mtWhin) {
        mtWhin.setUpdateTime(DateUtils.getNowDate());
        return mtWhinMapper.updateMtWhin(mtWhin);
    }

    /**
     * 批量删除美团入库单主
     *
     * @param ids 需要删除的美团入库单主ID
     * @return 结果
     */
    @Override
    public int deleteMtWhinByIds(Long[] ids) {
        return mtWhinMapper.deleteMtWhinByIds(ids);
    }

    /**
     * 删除美团入库单主信息
     *
     * @param id 美团入库单主ID
     * @return 结果
     */
    @Override
    public int deleteMtWhinById(Long id) {
        return mtWhinMapper.deleteMtWhinById(id);
    }


    /**
     * 处理美团出入库信息表中的日期大于店铺同步日期、小于当前日期的待同步（状态为50）数据，
     * 逐日处理、按日、按店铺、按供应商、按物料汇总生成ERP系统出入库单，
     * 生成MTYYMMnnn格式的ERP订单编号写入到美团出入库主单、及ERP系统出入库单主表的business_code中，
     * 并更新状态为100-已同步。
     * ERP系统中出入库类型不需要扩展（记录采购入库、销售出库），
     * 通过business_code来区分订单来自于美团（MTYYMMnnn）还是ERP系统内部。
     * 美团采购入库单对应生成ERP采购入库单，销售出库单丢弃，
     * 所有美团非采购入库、销售入库类型的出入库单对应ERP系统的其他出入库单。
     */
    @Override
    @Transactional
    public void whinDataPush(List<MtShop> mtShopList) {
        for (MtShop shop : mtShopList) {
            int pushDays = shop.getPushDays();
            HashMap<String, Date> PUSH_DATE = mtShopService.getPushDate(shop);
            Date bizTimeLastEnd = PUSH_DATE.get("bizTimeLastEnd");
            Date bizTimeEnd = PUSH_DATE.get("bizTimeEnd");
            Date bizTimeStart = PUSH_DATE.get("bizTimeStart");

            while (0 < DateUtils.getDateDiff(bizTimeLastEnd, bizTimeEnd)) {
                //入库
                MtWhin mtWhin = new MtWhin();
                mtWhin.setMtShopld(shop.getId());
                mtWhin.setMtCreatedtimeStart(bizTimeStart.getTime());
                mtWhin.setMtCreatedtimeEnd(bizTimeEnd.getTime());
                mtWhin.setStatusNo(new Integer[]{30, 50});
                List<MtWhin> mtWhinList = mtWhinMapper.selectMtWhinList(mtWhin);
                if (mtWhinList.size() > 0) {
                    log.info("数据未处理完成！");
                    return;
                }

                mtWhin.setStatus(50);
                mtWhin.setErpTypeNo9(9);
                List<MtWhinitem> whinitems = mtWhinMapper.dataForErpWhin(mtWhin);

                mtWhin.setStatusNo(null);//之后更新查询去掉此条件
                if (whinitems.size() > 0) {
                    String businesscode = codeService.getCode("34");
                    Set<Integer> erpTypeSet = new HashSet<>();
                    for (int i = 0; i < whinitems.size(); i++) {
                        erpTypeSet.add(whinitems.get(i).getErpType());
                    }

                    Iterator iterator = erpTypeSet.iterator();
                    while (iterator.hasNext()) {
                        Integer erpType = (Integer) iterator.next();
                        setWhinform(whinitems, businesscode, erpType, null, bizTimeEnd, shop.getSysuserid());
                    }

                    updateMtWhin(mtWhin, businesscode);
                }
                //采购入库
                mtWhin.setErpTypeNo9(null);
                mtWhin.setErpType(9);
                List<MtWhinitem> whinitems9 = mtWhinMapper.dataForErpWhin(mtWhin);
                if (whinitems9.size() > 0) {
                    String businesscode = codeService.getCode("33");
                    Set<Long> erpTypeSet = new HashSet<>();
                    for (int i = 0; i < whinitems9.size(); i++) {
                        erpTypeSet.add(whinitems9.get(i).getSupplierid());
                    }

                    Iterator iterator = erpTypeSet.iterator();
                    while (iterator.hasNext()) {
                        Long supplierId = (Long) iterator.next();
                        setWhinform(whinitems9, businesscode, 9, supplierId, bizTimeEnd, shop.getSysuserid());
                    }
                    updateMtWhin(mtWhin, businesscode);
                }

                //4. 更新起始日期
                bizTimeStart = DateUtils.addSeconds(bizTimeEnd, 1);
                bizTimeEnd = DateUtils.addDay(bizTimeEnd, pushDays);
            }
            mtShopService.updateShopByPush(shop, whin_state, bizTimeEnd);
        }
    }

    private void updateMtWhin(MtWhin mtWhin, String businesscode) {
        List<MtWhin> mtWhinList = mtWhinMapper.selectMtWhinList(mtWhin);
        for (MtWhin whin : mtWhinList) {
            whin.setCode(businesscode);
            whin.setStatus(100);
            mtWhinMapper.updateMtWhin(whin);
        }
    }

    private void setWhinform(List<MtWhinitem> items, String businesscode, Integer erpType,
                             Long supplierId, Date bizTimeEnd, Long sysuserid) {
        SysUser sysUser = sysUserService.selectUserById(sysuserid);
        String whoutGuid = IdUtils.fastSimpleUUID();
        String orgguid = null;
        BigDecimal weight = new BigDecimal(0);
        MtWhinitem mtWhinitem = null;
        for (int i = 0; i < items.size(); i++) {

            MtWhinitem mtItem = items.get(i);
            if (mtItem.getErpType() == erpType) {

                if (erpType == 9) {//采购入库-不同供应商
                    if (mtItem.getSupplierid().intValue() != supplierId.intValue()) {
                        log.info("不同供应商跳过" + mtItem.getErpWeight());
                        continue;
                    }
                }

                mtWhinitem = mtItem;
                Organization organization = organizationMapper.selectOrganizationByAutoId(mtWhinitem.getOrgId());
                orgguid = organization.getGuid();
                Whinformitem item = new Whinformitem();
                item.setGuid(IdUtils.fastSimpleUUID());
                item.setWhinid(whoutGuid);
                item.setSrguid(mtItem.getStoreroomguid());
                item.setShrguid(mtItem.getStorehouseguid());
                item.setProductguid(mtItem.getProductguid());
                item.setSpguid(mtItem.getSpguid());
                item.setOrgguid(orgguid);
                item.setOrgname(mtItem.getOrgName());
                item.setWeight(mtItem.getErpWeight());
                item.setPrice(mtItem.getErpPrice());
                item.setStockunitid(mtItem.getStockunitid());
                item.setAmount(mtItem.getAmount());
                item.setStockunit(mtItem.getStockunitname());
                item.setCreateTime(DateUtils.getNowDate());
                item.setSpename(mtItem.getSpname());
                whinformitemMapper.insertWhinformitem(item);
                weight = weight.add(item.getWeight());
                //更新库存
                this.updateWhinfo(item);
                //更新动态库存
                whoutformService.syncWhinfoRecords(item, bizTimeEnd, bizTimeEnd);
            }
        }

        //组装入库单
        Whinform form = new Whinform();
        form.setChannel(InFormChannelEnums.MT.getCode());
        form.setGuid(whoutGuid);
        form.setFormno(businesscodeService.getCode("4"));
        form.setDepartmentid(mtWhinitem.getDepartmentguid());
        form.setBusinesscode(businesscode);
        form.setStorermguid(mtWhinitem.getStoreroomguid());
        form.setStorehguid(mtWhinitem.getStorehouseguid());
        form.setProductid(mtWhinitem.getProductguid());
        form.setProductname(mtWhinitem.getProductname());
//        form.setFoguid(mtWhinitem.getGuid());
//        form.setOperatorid(user.getGuid());
        form.setOrgguid(orgguid);
        form.setOrgname(mtWhinitem.getOrgName());
        form.setSettlOrgId(orgguid);
        form.setSettlOrgName(mtWhinitem.getOrgName());
        form.setWhintype(erpType);
        if (erpType == 9) {
            form.setSupplierId(mtWhinitem.getSupplierid());
            form.setSupplierName(mtWhinitem.getSupplierName());
        }
        form.setCurrency(1);
        form.setIsCopytoKD(1);
        form.setCreatedate(DateUtils.getNowDate());
        form.setOperatorid(sysUser.getTuserId());
        form.setWeight(weight);
        whinformMapper.insertWhinform(form);
    }

    public void updateWhinfo(Whinformitem item) {

        // 更新库存信息
        Whinfo info = whinfoService.getWhinfo(item.getOrgguid(), item.getProductguid(), item.getSrguid(),
                item.getShrguid(), item.getSpguid());
        if (info != null) {
            Whinfo upinfo = new Whinfo();
            upinfo.setGuid(info.getGuid());
            upinfo.setStoreqty(info.getStoreqty().add(item.getWeight()));
            whinfoService.updateWhinfo(upinfo);
        } else {
            Whinfo whinfo = new Whinfo();
            whinfo.setGuid(IdUtils.fastSimpleUUID());
            whinfo.setStorermguid(item.getSrguid());
            whinfo.setStorehguid(item.getShrguid());
            whinfo.setProductid(item.getProductguid());
            whinfo.setSpguid(item.getSpguid());
            whinfo.setStoreqty(item.getWeight());
            whinfo.setCreatedate(new Date());
            whinfo.setOrgguid(item.getOrgguid());
            whinfo.setStockunit(item.getStockunit());
            whinfo.setStockunitid(item.getStockunitid());
            whinfo.setPrice(item.getPrice());
            whinfo.setProductname(item.getSpename());
            whinfoService.insertWhinfo(whinfo);
        }
    }


    @Override
    @Transactional
    public void dataPull(List<MtShop> mtShopList) {
        log.info("入库单拉取"+this.getClass() + DateUtils.getTime());
//        Date yestoday = DateUtils.addDays(DateUtils.getNowDate(), -1);
        MtToken mtToken = iMtTokenService.getLastTokenByConditions(new MtToken());

        for (MtShop shop : mtShopList) {
            //获取当前店铺与昨天的天数差
//            long dateDiff = DateUtils.getDateDiff(yestoday, shop.getPulldate());
//            for (int i = 0; i < dateDiff; i++) {

            try {
                dataPullWithShop(mtToken, shop);
            } catch (Exception e) {
                throw new CustomException(e.getMessage());
            }

            String autoroll = sysConfigService.selectConfigByKey("mtpulldate_autoroll");
                if(StringUtils.isNotBlank(autoroll)&&autoroll.equalsIgnoreCase("false")){
                    log.info("美团拉取数据日期不自动滚动！");
                    return;
                }
//            }
            log.info("入库单拉取"+this.getClass() + DateUtils.getTime());
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public void dataPullWithShop(MtToken mtToken, MtShop shop)  throws Exception {
        Date pulldate = shop.getPulldate();
        Long timeBegin = pulldate.getTime();
        Long timeEnd = DateUtils.getLastDayOfDate(pulldate).getTime();
        //获取MT接口数据9
        mtPullService.getWhin(shop, timeBegin, timeEnd, mtToken);
        //转换为业务实体，并插入,如果已存在对应ID的实体，则跳过
        if (!shop.isPullFinished(whin_state)){
            shop.setPullState(whin_state, 1);
        }
        mtShopService.checkAndInitPullDate(shop);
        mtShopService.updateMtShop(shop);
    }
}
